﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.IO;
using System.Xml.Serialization;
using System.Reflection;

namespace System.Data.DataSetGenerator
{
    /// <summary>
    /// Represents a configuration for the DataSets and typed DataAdapters generator.
    /// </summary>
    [Serializable]
    [XmlType("Configuration")]
    public class TypedDataSetGeneratorConfiguration
    {
        /// <summary>
        /// Initializes a new instance of the TypedDataSetGeneratorConfiguration class.
        /// </summary>
        public TypedDataSetGeneratorConfiguration()
        {
            Util.InitializeObject(this);
        }

        /// <summary>
        /// Serializes the config to the given stream.
        /// </summary>
        /// <param name="stream"></param>
        public void Save(Stream stream)
        {
            if (stream == null)
                throw new ArgumentNullException("stream");

            stream.Position = 0;
            XmlSerializer serializer = new XmlSerializer(typeof(TypedDataSetGeneratorConfiguration));
            serializer.Serialize(stream, this);
            stream.Flush();
        }

        /// <summary>
        /// Saves the config to the given file
        /// </summary>
        /// <param name="fileName">File to save</param>
        public void Save(String fileName)
        {
            if (String.IsNullOrEmpty(fileName))
                throw new ArgumentNullException("fileName");

            using (FileStream stream = new FileStream(fileName, FileMode.Create))
            {
                Save(stream);
            }
        }

        /// <summary>
        /// Loads a config from given stream.
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        public static TypedDataSetGeneratorConfiguration Load(Stream stream)
        {
            if (stream == null)
                throw new ArgumentNullException("stream");

            stream.Position = 0;

            // TODO: validate version
            var schemaStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("System.Data.DataSetGenerator.Config_1_0.xsd");
            Util.Validate(stream, schemaStream); 

            stream.Position = 0;
            XmlSerializer serializer = new XmlSerializer(typeof(TypedDataSetGeneratorConfiguration), "");
            return (TypedDataSetGeneratorConfiguration)serializer.Deserialize(stream);
        }

        /// <summary>
        /// Loads a config given its path.
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static TypedDataSetGeneratorConfiguration Load(String fileName)
        {
            if (String.IsNullOrEmpty(fileName))
                throw new ArgumentNullException(fileName);

            if (!File.Exists(fileName))
                throw new FileNotFoundException("File not found", fileName);

            using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
            {
                return Load(stream);
            }
        }

        private DataSetCollection dataSets;


        /// <summary>
        /// Returns the DataSets collection from the config.
        /// </summary>
        public DataSetCollection DataSets
        {
            get
            {
                if (dataSets == null)
                    dataSets = new DataSetCollection();
                return dataSets;
            }
        }

        internal List<String> dataSetsToInclude;

        internal List<String> DataSetsToInclude
        {
            get
            {
                if (dataSetsToInclude == null)
                    dataSetsToInclude = new List<string>();
                return dataSetsToInclude;
            }
        }

        private DataAdaptersSection dataAdaptersSection;


        /// <summary>
        /// Returns the DataAdapter configuration section from the config.
        /// </summary>
        public DataAdaptersSection DataAdapters
        {
            get
            {
                if (dataAdaptersSection == null)
                    dataAdaptersSection = new DataAdaptersSection();
                return dataAdaptersSection;
            }
            set
            {
                dataAdaptersSection = value;
            }
        }

        /// <summary>
        /// Gets the connection string that is used to connect to the Sql Server Database.
        /// </summary>
        [DefaultValue("")]
        [XmlAttribute]
        public String ConnectionString { get; set; }


        /// <summary>
        /// Sets the particular programming language name for the DataSets and DataAdapters code generator. Default is CS (CSharp).
        /// </summary>
        [DefaultValue(LanguageEnum.CS)]
        [XmlAttribute]
        public LanguageEnum Language { get; set; }
    }
}
